package service

import (
	"errors"
	"go-admin/app/admin/models"

	log "github.com/go-admin-team/go-admin-core/logger"
	"go-admin/app/admin/service/dto"
	cDto "go-admin/common/dto"
	"gorm.io/gorm"

	"github.com/go-admin-team/go-admin-core/sdk/service"
)

type SysMemberType struct {
	service.Service
}

// GetPage 获取SysMemberType列表
//func (e *SysMemberType) GetPage(c *dto.SysSysMemberTypePageReq, list *[]models.SysMemberType) error {
//	var err error
//	var data models.SysMemberType
//
//	err = e.Orm.Model(&data).
//		Scopes(
//			cDto.MakeCondition(c.GetNeedSearch()),
//		).
//		Find(list).Error
//	if err != nil {
//		e.Log.Errorf("db error:%s", err)
//		return err
//	}
//	return nil
//}

// Get 获取SysMemberType对象
func (e *SysMemberType) Get(d *dto.SysMemberTypeGetReq, model *models.SysMemberType) error {
	var err error
	var data models.SysMemberType

	db := e.Orm.Model(&data).
		First(model, d.GetId())
	err = db.Error
	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
		err = errors.New("查看对象不存在或无权查看")
		e.Log.Errorf("db error:%s", err)
		return err
	}
	if db.Error != nil {
		e.Log.Errorf("db error:%s", err)
		return err
	}
	return nil
}

// Insert 创建SysMemberType对象
func (e *SysMemberType) Insert(c *dto.SysMemberTypeInsertReq) error {
	var err error
	var data models.SysMemberType
	var i int64
	err = e.Orm.Model(&data).Where("type_name = ?", c.TypeName).Count(&i).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return err
	}
	if i > 0 {
		err := errors.New("用户类型已存在！")
		e.Log.Errorf("db error: %s", err)
		return err
	}
	c.Generate(&data)
	tx := e.Orm.Debug().Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	err = tx.Create(&data).Error
	if err != nil {
		e.Log.Errorf("db error:%s", err)
		return err
	}
	return nil
}

// Update 修改SysMemberType对象
func (e *SysMemberType) Update(c *dto.SysMemberTypeUpdateReq) error {
	var err error
	var model = models.SysMemberType{}
	tx := e.Orm.Debug().Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	tx.First(&model, c.GetId())
	c.Generate(&model)

	if model.ParentId != 0 {
		var types models.SysMemberType
		tx.First(&types, model.ParentId)
	}
	db := tx.Save(&model)
	if db.Error != nil {
		e.Log.Errorf("UpdateSysDept error:%s", err)
		return err
	}
	if db.RowsAffected == 0 {
		return errors.New("无权更新该数据")
	}
	return nil
}

// Remove 删除SysMemberType
func (e *SysMemberType) Remove(d *dto.SysMemberTypeDeleteReq) error {
	var err error
	var data models.SysMemberType

	db := e.Orm.Model(&data).Delete(&data, d.GetId())
	if db.Error != nil {
		err = db.Error
		e.Log.Errorf("Delete error: %s", err)
		return err
	}
	if db.RowsAffected == 0 {
		err = errors.New("无权删除该数据")
		return err
	}
	return nil
}

// GetSysMemberTypeList 获取组织数据
func (e *SysMemberType) getList(c *dto.SysMemberTypeGetPageReq, list *[]models.SysMemberType) error {
	var err error
	var data models.SysMemberType

	err = e.Orm.Model(&data).
		Scopes(
			cDto.MakeCondition(c.GetNeedSearch()),
		).
		Find(list).Error
	if err != nil {
		e.Log.Errorf("db error:%s", err)
		return err
	}
	return nil
}

// SetDeptTree 设置组织数据
func (e *SysMemberType) SetMemberTypeTree(c *dto.SysMemberTypeGetPageReq) (m []dto.TypeLabel, err error) {
	var list []models.SysMemberType
	err = e.getList(c, &list)

	m = make([]dto.TypeLabel, 0)
	for i := 0; i < len(list); i++ {
		if list[i].ParentId != 0 {
			continue
		}
		e := dto.TypeLabel{}
		e.Id = list[i].Id
		e.Label = list[i].TypeName
		typesInfo := typeTreeCall(&list, e)

		m = append(m, typesInfo)
	}
	return
}

// Call 递归构造组织数据
func typeTreeCall(typeList *[]models.SysMemberType, types dto.TypeLabel) dto.TypeLabel {
	list := *typeList
	min := make([]dto.TypeLabel, 0)
	for j := 0; j < len(list); j++ {
		if types.Id != list[j].ParentId {
			continue
		}
		mi := dto.TypeLabel{Id: list[j].Id, Label: list[j].TypeName, Children: []dto.TypeLabel{}}
		ms := typeTreeCall(typeList, mi)
		min = append(min, ms)
	}
	types.Children = min
	return types
}

// SetDeptPage 设置dept页面数据
func (e *SysMemberType) SetMemberTypePage(c *dto.SysMemberTypeGetPageReq) (m []models.SysMemberType, err error) {
	var list []models.SysMemberType
	err = e.getList(c, &list)
	for i := 0; i < len(list); i++ {
		if list[i].ParentId != 0 {
			continue
		}
		info := e.typePageCall(&list, list[i])
		m = append(m, info)
	}
	return
}

func (e *SysMemberType) typePageCall(typelist *[]models.SysMemberType, menu models.SysMemberType) models.SysMemberType {
	list := *typelist
	min := make([]models.SysMemberType, 0)
	for j := 0; j < len(list); j++ {
		if menu.Id != list[j].ParentId {
			continue
		}
		mi := models.SysMemberType{}
		mi.Id = list[j].Id
		mi.ParentId = list[j].ParentId
		mi.TypeName = list[j].TypeName
		mi.Sort = list[j].Sort
		mi.Status = list[j].Status
		mi.CreatedAt = list[j].CreatedAt
		mi.Children = []models.SysMemberType{}
		ms := e.typePageCall(typelist, mi)
		min = append(min, ms)
	}
	menu.Children = min
	return menu
}

func (e *SysMemberType) SetTypeLabel() (m []dto.TypeLabel, err error) {
	list := make([]models.SysMemberType, 0)
	err = e.Orm.Find(&list).Error
	if err != nil {
		log.Error("find dept list error, %s", err.Error())
		return
	}
	m = make([]dto.TypeLabel, 0)
	var item dto.TypeLabel
	for i := range list {
		if list[i].ParentId != 0 {
			continue
		}
		item = dto.TypeLabel{}
		item.Id = list[i].Id
		item.Label = list[i].TypeName
		typeInfo := typeLabelCall(&list, item)
		m = append(m, typeInfo)
	}
	return
}

// typeLabelCall
func typeLabelCall(typeList *[]models.SysMemberType, types dto.TypeLabel) dto.TypeLabel {
	list := *typeList
	var mi dto.TypeLabel
	min := make([]dto.TypeLabel, 0)
	for j := 0; j < len(list); j++ {
		if types.Id != list[j].ParentId {
			continue
		}
		mi = dto.TypeLabel{Id: list[j].Id, Label: list[j].TypeName, Children: []dto.TypeLabel{}}
		ms := typeLabelCall(typeList, mi)
		min = append(min, ms)
	}
	types.Children = min
	return types
}
